package emby.lang;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import emby.err.InvalidArgumentError;
import emby.err.TypeError;
import emby.overload.OverloadDot;
import emby.overload.OverloadIndex;
import emby.overload.OverloadType;

public class EmbyList extends EmbyObject implements Iterable<Object>,OverloadIndex, OverloadDot, OverloadType {

	private List<Object> contents;
	public EmbyList(){
		contents = new ArrayList<Object>();
	}
	public  EmbyList(List<Object> contents){
		this.contents =  contents;
	}

	public List<Object> getContents(){
		return contents;
	}

	@Override
	public Object get_dot(int line, String o) {
		if (o.equals("length")){
			return contents.size();
		}else if(o.equals("add")){
			return add;
		}else if(o.equals("remove")){
			return remove;
		}else if(o.equals("slice")){
			return slice;
		}
		else if (o.equals("javaArray")){
			return contents;
		}
		else{
			throw new TypeError(line,"Array has no attribute: "+o);
			//return null;
		}
	}

	@Override
	public void set_dot(int line, String o, Object new_value) {
		throw new TypeError(line,"Attemted to assign values to array stuffs. ");
	}

	@Override
	public Object get_index(int errline, Object o) {
		if (!(o instanceof Integer)){
			throw new TypeError(errline,"Arrays must be indexed by integers. "+o);
		}
		int i = (Integer)o;
		return contents.get(i);
	}

	@Override
	public void set_index(int errline, Object index, Object new_value) {
		if (!(index instanceof Integer)){
			throw new TypeError(errline,"Arrays must be indexed by integers");
		}
		int i = (Integer)index;
		contents.set(i, new_value);
	}

	@Override
	public Object operatorType(int line, Scope s) {
		return "list";
	}

	@Override
	public Iterator<Object> iterator() {
		return contents.iterator();
	}

	public String toString(){
		return contents.toString();
	}

	public  NativeFunction add = new NativeFunction("add",-1){
		private static final long serialVersionUID = 8572943857337772854L;
		public Object execute(int line, Scope s, Object... args){
			if( args== null || args.length!=1){
				throw new InvalidArgumentError(line,"Add requires 1 argument");
			}
			contents.add(args[0]);
			return EmbyNull.Null;
		}
	};

	public  NativeFunction remove = new NativeFunction("remove",-1){
		private static final long serialVersionUID = 8572943857337772854L;
		public Object execute(int line, Scope s, Object... args){
			if( args== null || args.length!=1){
				throw new InvalidArgumentError(line,"Remove requires 1 argument");
			}
			return contents.remove(args[0]);
		}
	};

	public  NativeFunction slice = new NativeFunction("slice",-1){
		private static final long serialVersionUID = 8572943857337772854L;
		public Object execute(int line, Scope s, Object... args){
			if( args== null || args.length!=2){
				throw new InvalidArgumentError(line,"Slice requires 2 arguments");
			}
			if( args[0] instanceof Integer && args[1] instanceof Integer){
				int a = (Integer)args[0];
				int b = (Integer)args[1];
				return new EmbyList(contents.subList(a, b));
			}else{
				throw new TypeError(line, "Slice requires integers as arguments");
			}
		}
	};


}
